﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;

namespace ParticleFiltersDemo1
{
    public class Robot : ViewModelBase
    {
        public double speed = 1; // stypka
        private double x; // coordinates in the matrix
        private double y;
        private Random random = new Random();

        double heading;
        Board board;
        public bool noisy;
        int stepCount;

        public double Heading
        {
            get
            {
                return this.heading;
            }
        }

        public Action PositionChanged;

        public double X
        {
            get
            {
                return this.x;
            }
            set
            {
                if ( this.x == value )
                    return;

                this.x = value;
                this.NotifyPropertyChanged( "X" );
            }
        }

        public double Y
        {
            get
            {
                return this.y;
            }
            set
            {
                if ( this.y == value )
                    return;

                this.y = value;
                this.NotifyPropertyChanged( "Y" );
            }
        }

        public Robot( Board board )
            : this( 0, 0, 0, false, board )
        {

        }

        public Robot( double x, double y, double heading, bool noisy, Board board )
        {
            this.X = x;
            this.Y = y;
            this.heading = heading;
            this.noisy = noisy;
            this.board = board;
            stepCount = 0;

            if ( this.PositionChanged != null )
                this.PositionChanged();
        }

        public void ReadSensor()
        {
            //TODO
        }

        public bool IsNextToObstacle
        {
            get
            {
                double rad = heading * Math.PI / 180;
                double dx = Math.Sin(rad) * speed;
                double dy = Math.Cos(rad) * speed;

                if (board.IsEmpty((int)(x + dx), (int)(y + dy)))
                {
                    return true;
                }
                return false;
            }
            
        }

        public bool Move()
        {
            bool hasMoved = false;

            while ( hasMoved == false )
            {
                hasMoved = this.AdvanceBy( speed, noisy );
                if ( hasMoved == false )
                    this.RandomHeading();
            }

            return true; // the robot has moved
        }

        bool AdvanceBy( double speed, bool noisy )
        {
            if ( noisy )
            {
                Random r = new Random();
                heading += r.Next( -3, 3 );
            }

            double rad = heading * Math.PI / 180;
            double dx = Math.Sin( rad ) * speed;
            double dy = Math.Cos( rad ) * speed;

            if ( board.IsEmpty( ( int )( x + dx ), ( int )( y + dy ) ) )
            {
                this.X += dx;
                this.Y += dy;

                if ( this.PositionChanged != null )
                    this.PositionChanged();

                return true;
            }

            return false;
        }

        void RandomHeading()
        {
            int x = this.random.Next( 0, 50 );
            heading = x % 2 == 0 ? heading + 90 : heading - 90;
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
}
